package com.fas.hehe.system.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import org.junit.Assert;

import com.fas.core.BaseService;
import com.fas.core.constant.R;
import com.fas.core.plugin.datatables.PageRequest;
import com.fas.core.plugin.jfinal.kit.ModelKit;
import com.fas.core.plugin.shiro.kit.PasswordKit;
import com.fas.core.util.sequence.Sequence;
import com.fas.hehe.system.model.Organization;
import com.fas.hehe.system.model.Role;
import com.fas.hehe.system.model.User;
import com.fas.hehe.system.model.UserDetail;
import com.fas.hehe.system.model.UserOfRole;
import com.jfinal.aop.Before;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;

/**
 * 
 * @ClassName: UserService
 * @Description: 用户业务处理类
 * @Copyright: Copyright (c) 2016 FAS
 * @anthor yixiaoping<thinker1013@163.com>
 * @since 2016年1月29日 上午12:05:09
 * @version V1.0
 */
public class UserService extends BaseService {
	/**
	 * 
	 * @Title:changePassword
	 * @Description: 修改密码
	 * @param userId
	 *            用户ID
	 * @param newPassword
	 *            新密码（未加密）
	 * @return boolean 返回类型 true:成功， false：失败
	 * @throws
	 * @anthor yixiaoping<thinker163@163.com>
	 * @date 2016年1月29日 上午12:05:31
	 */
	public boolean changePassword(Long userId, String newPassword) {
		User user = User.dao.findById(userId);
		user.setPassword(newPassword);
		PasswordKit.me().encryptPassword(user);
		return user.update();
	}

	/**
	 * 
	 * @Title:resetPassword
	 * @Description: 重置密码 1） 随机生成六位长度的字母+数字混合 2） 加密处理，更新用户密码
	 * 
	 * @param userId
	 *            用户ID
	 * @return String 返回类型 新密码（未加密）
	 * @throws
	 * @anthor yixiaoping<thinker163@163.com>
	 * @date 2016年1月29日 上午12:06:11
	 */
	public String resetPassword(Long userId) {
		String newPassword = PasswordKit.me().randomPassword();
		boolean result = this.changePassword(userId, newPassword);
		if (result) {
			return newPassword;
		}
		return null;
	}

	/**
	 * 
	 * @Title:findByUserId
	 * @Description: 根据用户ID查找用户
	 * @param userId
	 *            用户ID
	 * @return User 返回类型
	 * @throws
	 * @anthor yixiaoping<thinker163@163.com>
	 * @date 2016年1月29日 上午12:07:41
	 */
	public User findByUserId(Long userId) {
		return User.dao.findById(userId);
	}

	/**
	 * 
	 * @Title:findByUsername
	 * @Description: 根据用户名查找用户
	 * @param username
	 *            用户帐号
	 * @return User 返回类型
	 * @throws
	 * @anthor yixiaoping<thinker163@163.com>
	 * @date 2016年1月29日 上午12:07:54
	 */
	public User findByUsername(String username) {
		String sql = "select * from sys_user where username = ?";
		return User.dao.findFirst(sql, username);
	}

	/**
	 * 
	 * @Title:findByEmail
	 * @Description: 根据邮箱查找用户
	 * @param email
	 *            电子邮箱
	 * @return User 返回类型
	 * @throws
	 * @anthor yixiaoping<thinker163@163.com>
	 * @date 2016年1月29日 上午12:08:06
	 */
	public User findByEmail(String email) {
		String sql = "select * from sys_user where email = ?";
		return User.dao.findFirst(sql, email);
	}

	/**
	 * 
	 * @Title:findByMobile
	 * @Description: 根据手机号码查找用户
	 * @param mobile
	 *            手机号码
	 * @return User 返回类型
	 * @throws
	 * @anthor yixiaoping<thinker163@163.com>
	 * @date 2016年1月29日 上午12:08:14
	 */
	public User findByMobile(String mobile) {
		String sql = "select * from sys_user where mobile = ?";
		return User.dao.findFirst(sql, mobile);
	}

	/**
	 * 
	 * @Title:findRoles
	 * @Description: 根据用户ID，查询用户拥有的角色ID集合
	 * @param userId
	 *            用户ID
	 * @return Set<Long> 返回类型 角色ID集合
	 * @throws
	 * @anthor yixiaoping<thinker163@163.com>
	 * @date 2016年1月29日 上午12:08:21
	 */
	public Set<Long> findRoles(Long userId) {
		Set<Long> roleIdSet = Collections.emptySet();

		String sql = "select role_id from sys_user_of_role where user_id = ?";
		List<UserOfRole> userRoleList = UserOfRole.dao.find(sql, userId);

		roleIdSet = new TreeSet<Long>(); // 拥有的角色ID列表
		for (UserOfRole ur : userRoleList) {
			roleIdSet.add(ur.getRoleId());
		}
		return roleIdSet;
	}

	/**
	 * 
	 * @Title:findRolesStr
	 * @Description: 根据用户ID查找其角色
	 * @param userId
	 *            用户ID
	 * @return Set<String> 返回类型 角色ID集合（String类型）
	 * @throws
	 * @anthor yixiaoping<thinker163@163.com>
	 * @date 2016年1月29日 上午12:09:47
	 */
	public Set<String> findRolesStr(Long userId) {
		Set<Long> roleIdSet = this.findRoles(userId);
		Set<String> roleIdStrSe = new TreeSet<String>();
		for (Long roleId : roleIdSet) {
			roleIdStrSe.add(roleId.toString());
		}
		return roleIdStrSe;
	}

	/**
	 * 
	 * @Title:findPermissions
	 * @Description: 根据用户名查找其权限
	 * @param userId
	 *            用户ID
	 * @return Set<String> 返回类型 用户资源权限集合
	 * @throws
	 * @anthor yixiaoping<thinker163@163.com>
	 * @date 2016年1月29日 上午12:10:25
	 */
	public Set<String> findPermissions(Long userId) {
		return new RoleService().findPermissions(this.findRoles(userId));
	}

	/**
	 * 
	 * @Title:findResources
	 * @Description: 根据用户ID查询资源权限ID
	 * @param userId
	 *            用户ID
	 * @return Set<Long> 返回类型 用户拥有的资源ID集合
	 * @throws
	 * @anthor yixiaoping<thinker163@163.com>
	 * @date 2016年1月29日 上午12:10:59
	 */
	public Set<Long> findResources(Long userId) {
		return new RoleService().findResourceIds(this.findRoles(userId));
	}

	/**
	 * 
	 * @Title:queryPage
	 * @Description: 用户列表分页查询
	 * @param request
	 *            分页查询请求封装对象
	 * @see com.fas.core.plugin.datatables.PageRequest
	 * @return 参数说明
	 * @return Page<Record> 返回类型
	 * @throws
	 * @anthor yixiaoping<thinker163@163.com>
	 * @date 2016年1月29日 上午12:11:39
	 */
	public Page<Record> queryPage(PageRequest request) {
		Assert.assertNotNull("请求参数不能为空", request);

		Map<String, Object> paramsMap = request.getParams();
		ArrayList<Object> params = new ArrayList<Object>();
		String selectSql = "select * ";
		StringBuffer whereSql = new StringBuffer();
		whereSql.append(" from sys_user where 1=1 ");

		if (StrKit.notBlank((String) paramsMap.get("username"))) {
			whereSql.append(" and username = ?");
			params.add(paramsMap.get("username"));
		}
		if (StrKit.notBlank((String) paramsMap.get("mobile"))) {
			whereSql.append(" and mobile = ?");
			params.add(paramsMap.get("mobile"));
		}
		if (StrKit.notBlank((String) paramsMap.get("email"))) {
			whereSql.append(" and email = ?");
			params.add(paramsMap.get("email"));
		}
		if (StrKit.notBlank((String) paramsMap.get("available"))) {
			whereSql.append(" and available = ?");
			params.add(paramsMap.get("available"));
		}

		if (StrKit.notBlank((String) request.getOderby())) {
			whereSql.append(" order by ").append(request.getOderby());
		}

		return Db.paginate(request.getPageNumber(), request.getPageSize(), selectSql, whereSql.toString(),
				params.toArray());
	}

	/**
	 * 
	 * @Title:saveUser
	 * @Description: 保存用户信息 包括基本信息、详细信息
	 * @param user
	 *            用户对象
	 * @param userDetail
	 *            用户详细信息对象
	 * @return void 返回类型
	 * @throws
	 * @anthor yixiaoping<thinker163@163.com>
	 * @date 2016年1月29日 上午12:12:55
	 */
	@Before(Tx.class)
	public void saveUser(User user, UserDetail userDetail) {
		Long userId = user.getId();
		if (userId == null) {
			userId = Sequence.getSequence();
			user.setId(userId);
			user.setAvailable(Integer.valueOf(R.Dict.STATUS_AVAILABLE));
			user.setLocked(Integer.valueOf(R.Dict.IS_OR_NOT_N));
			Organization org = new OrganizationService().findOrganizationById(user.getCompanyId());
			user.setOrgFullPath(org.getPath());

			user.setPassword(R.Const.DEFAULT_UESR_PWD);
			PasswordKit.me().encryptPassword(user);
			user.save();
			userDetail.save();
		} else {

			User oldUser = User.dao.findById(userId);
			oldUser.setUsernameZh(user.getUsernameZh());
			oldUser.setEmail(user.getEmail());
			oldUser.setMobile(user.getMobile());
			oldUser.setAvatar(user.getAvatar());
			Organization org = new OrganizationService().findOrganizationById(user.getCompanyId());
			oldUser.setOrgFullPath(org.getPath());

			oldUser.update();
			userDetail.update();
		}
	}

	/**
	 * 
	 * @Title:deleteUserById
	 * @Description: 根据用户ID删除用户 逻辑删除，将状态改为：0-不可用
	 * @param userId
	 *            用户ID
	 * @return 参数说明
	 * @return boolean 返回类型 true：删除成功，false：删除失败
	 * @throws
	 * @anthor yixiaoping<thinker163@163.com>
	 * @date 2016年1月29日 上午12:15:23
	 */
	public boolean deleteUserById(Long userId) {
		User oldData = User.dao.findById(userId);
		User newData = new User();
		ModelKit.clone(oldData, newData);

		oldData.set("available", R.Dict.STATUS_UNAVAILABLE);
		oldData.update();
		this.saveOperateLog(R.OperType.UPDATE, newData, oldData, this.getLoginUser());
		return true;
	}

	/**
	 * 
	 * @Title:findUserDetailById
	 * @Description: 根据用户ID查询用户详细信息
	 * @param userId
	 *            用户ID
	 * @return UserDetail 返回类型
	 * @throws
	 * @anthor yixiaoping<thinker163@163.com>
	 * @date 2016年1月29日 上午12:16:09
	 */
	public UserDetail findUserDetailById(Long userId) {
		return UserDetail.dao.findById(userId);
	}

	/**
	 * 
	 * @Title:findUserOfRolesById
	 * @Description: 根据用户ID查询用户可以分配的角色范围内，【拥有】的和【没有拥有】的角色列表,
	 *               用于页面展现【用户已用于的角色】和【用户未赋予的角色】功能
	 * @param userId
	 *            用户ID
	 * @return List<Record> 返回类型
	 * @throws
	 * @anthor yixiaoping<thinker163@163.com>
	 * @date 2016年1月29日 上午12:16:31
	 */
	public List<Record> findUserOfRolesById(Long userId) {
		// 查询用户当前角色列表
		String sql = "select * from sys_user_of_role where user_id = ?";
		List<UserOfRole> uorList = UserOfRole.dao.find(sql, userId);
		Set<Long> hasRoleIdSet = new HashSet<Long>();
		for (UserOfRole uor : uorList) {
			hasRoleIdSet.add(uor.getRoleId());
		}

		// 查询当前登录用户所能操作的机构
		Long orgId = this.getCompanyId();// 加载用户所属公司组织机构树
		List<Organization> list = new OrganizationService().findSubOrgListById(orgId);

		String roleSql = "select * from sys_role where organization_id = ? and available = ?";
		List<Record> allRoleList = new ArrayList<Record>();
		for (Organization org : list) {
			List<Role> roleList = Role.dao.find(roleSql, org.getId(), R.Dict.STATUS_AVAILABLE);

			for (Role role : roleList) {
				Record rd = new Record();
				rd.set("roleid", role.getId());
				rd.set("rolename", role.getRole());
				rd.set("orgpath", org.getPath());
				if (hasRoleIdSet.contains(role.getId())) {
					rd.set("selected", true);// 用户赋予过该角色
				} else {
					rd.set("selected", false);
				}
				allRoleList.add(rd);
			}
		}
		return allRoleList;
	}

	/**
	 * 
	 * @Title:batchSaveUserOfRole
	 * @Description: 批量保存用户赋予的角色列表
	 * @param userId
	 *            用户ID
	 * @param roleIds
	 *            角色ID字符串，多个按逗号分隔。 例如： 1,2,3,
	 * @return 参数说明
	 * @return boolean 返回类型
	 * @throws
	 * @anthor yixiaoping<thinker163@163.com>
	 * @date 2016年1月29日 上午12:19:41
	 */
	@Before(Tx.class)
	public boolean batchSaveUserOfRole(Long userId, String roleIds) {
		if (StrKit.isBlank(roleIds) || roleIds.indexOf(",") == -1) {
			return true;
		}
		// 先删除用户原有的角色
		String sql = "delete from sys_user_of_role where user_id = ?";
		Db.update(sql, userId);

		// 保存新的角色权限
		List<UserOfRole> list = new ArrayList<UserOfRole>();
		String[] roles = roleIds.split(",");
		for (String roleId : roles) {
			UserOfRole uor = new UserOfRole();
			uor.setRoleId(Long.valueOf(roleId));
			uor.setUserId(userId);
			list.add(uor);
		}

		Db.batchSave(list, R.Const.DB_BATCH_SIZE);
		return true;
	}

}
